package top.zywork.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.zywork.annotation.AppAuthFilter;
import top.zywork.annotation.SysLog;
import top.zywork.annotation.XssFilter;
import top.zywork.common.*;
import top.zywork.constant.FileConstants;
import top.zywork.dto.GoodsSkuActivityDTO;
import top.zywork.dto.PagerDTO;
import top.zywork.dto.GoodsInfoDTO;
import top.zywork.enums.DatePatternEnum;
import top.zywork.enums.UploadTypeEnum;
import top.zywork.query.GoodsInfoQuery;
import top.zywork.service.GoodsInfoService;
import top.zywork.service.UploadService;
import top.zywork.vo.GoodsSkuActivityVO;
import top.zywork.vo.ResponseStatusVO;
import top.zywork.vo.PagerVO;
import top.zywork.vo.GoodsInfoVO;

import java.util.List;

/**
 * GoodsInfoController控制器类<br/>
 *
 * 创建于2019-07-04<br/>
 *
 * @author http://zywork.top 王振宇
 * @version 1.0
 */
@RestController
@RequestMapping("/goods-info")
@Slf4j
@XssFilter(ignoreUrls = {"/goods-info/admin/save",
        "/goods-info/admin/batch-save",
        "/goods-info/admin/update",
        "/goods-info/admin/batch-update"})
@AppAuthFilter(ignoreUrls = {
        "/goods-info/admin/upload-img"
})
public class GoodsInfoController extends BaseController {

    @Value("${storage.provider}")
    private String storageProvider;

    @Value("${storage.local.compressSizes}")
    private String compressSizes;

    @Value("${storage.local.compressScales}")
    private String compressScales;

    @Value("${storage.local.goods.imgParentDir}")
    private String imgParentDir;

    @Value("${storage.local.goods.imgDir}")
    private String imgDir;

    @Value("${storage.local.goods.imgUrl}")
    private String imgUrl;

    @Value("${storage.local.goods.keepFileName}")
    private Boolean keepFileName;

    private GoodsInfoService goodsInfoService;

    private UploadService uploadService;

    @PostMapping("admin/save")
    @SysLog(description = "后台保存GoodsInfoVO", requestParams = false)
    public ResponseStatusVO save(@RequestBody @Validated GoodsInfoVO goodsInfoVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        goodsInfoService.save(BeanUtils.copy(goodsInfoVO, GoodsInfoDTO.class));
        return ResponseStatusVO.ok("添加成功", null);
    }

    @PostMapping("admin/batch-save")
    @SysLog(description = "后台批量保存GoodsInfoVO", requestParams = false)
    public ResponseStatusVO saveBatch(@RequestBody @Validated List<GoodsInfoVO> goodsInfoVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        goodsInfoService.saveBatch(BeanUtils.copyListObj(goodsInfoVOList, GoodsInfoDTO.class));
        return ResponseStatusVO.ok("批量添加成功", null);
    }

    @GetMapping("admin/remove/{id}")
    @SysLog(description = "后台删除GoodsInfoVO")
    public ResponseStatusVO removeById(@PathVariable("id") Long id) {
        goodsInfoService.removeById(id);
        return ResponseStatusVO.ok("删除成功", null);
    }

    @PostMapping("admin/batch-remove")
    @SysLog(description = "后台批量删除GoodsInfoVO")
    public ResponseStatusVO removeByIds(@RequestBody String[] ids) {
        goodsInfoService.removeByIds(StringUtils.strArrayToLongArray(ids));
        return ResponseStatusVO.ok("批量删除成功", null);
    }

    @PostMapping("admin/update")
    @SysLog(description = "后台更新GoodsInfoVO", requestParams = false)
    public ResponseStatusVO update(@RequestBody @Validated GoodsInfoVO goodsInfoVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        return updateGoodsInfo(goodsInfoVO);
    }

    @PostMapping("admin/batch-update")
    @SysLog(description = "后台批量更新GoodsInfoVO", requestParams = false)
    public ResponseStatusVO updateBatch(@RequestBody @Validated List<GoodsInfoVO> goodsInfoVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        goodsInfoService.updateBatch(BeanUtils.copyListObj(goodsInfoVOList, GoodsInfoDTO.class));
        return ResponseStatusVO.ok("批量更新成功", null);
    }

    @PostMapping("admin/active")
    @SysLog(description = "后台激活或冻结GoodsInfoVO")
    public ResponseStatusVO active(@RequestBody GoodsInfoVO goodsInfoVO) {
        goodsInfoService.update(BeanUtils.copy(goodsInfoVO, GoodsInfoDTO.class));
        return ResponseStatusVO.ok("激活或冻结成功", null);
    }

    @PostMapping("admin/batch-active")
    @SysLog(description = "后台批量激活或冻结GoodsInfoVO")
    public ResponseStatusVO activeBatch(@RequestBody @Validated List<GoodsInfoVO> goodsInfoVOList) {
        goodsInfoService.updateBatch(BeanUtils.copyListObj(goodsInfoVOList, GoodsInfoDTO.class));
        return ResponseStatusVO.ok("批量激活或冻结成功", null);
    }

    @GetMapping("admin/one/{id}")
    public ResponseStatusVO getById(@PathVariable("id") Long id) {
        GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
        Object obj = goodsInfoService.getById(id);
        if (obj != null) {
            goodsInfoVO = BeanUtils.copy(obj, GoodsInfoVO.class);
        }
        return ResponseStatusVO.ok("查询成功", goodsInfoVO);
    }

    @GetMapping("admin/all")
    public ResponseStatusVO listAll() {
        PagerDTO pagerDTO = goodsInfoService.listAll();
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), GoodsInfoVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/all-cond")
    public ResponseStatusVO listAllByCondition(@RequestBody GoodsInfoQuery goodsInfoQuery) {
        PagerDTO pagerDTO = goodsInfoService.listAllByCondition(goodsInfoQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), GoodsInfoVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/pager-cond")
    public ResponseStatusVO listPageByCondition(@RequestBody GoodsInfoQuery goodsInfoQuery) {
        PagerDTO pagerDTO = goodsInfoService.listPageByCondition(goodsInfoQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), GoodsInfoVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/upload-img")
    @SysLog(description = "后台上传商品图片", requestParams = false)
    public ResponseStatusVO upload(MultipartFile file) {
        String date = DateFormatUtils.format(DateUtils.currentDate(), DatePatternEnum.DATE.getValue());
        UploadUtils.UploadOptions uploadOptions = UploadUtils.UploadOptions.builder().uploadParentDir(imgParentDir).uploadDir(imgDir + FileConstants.SEPARATOR + date)
                .dbSaveUrl(imgUrl + FileConstants.SEPARATOR + date).keepFileName(keepFileName).build();
        uploadOptions.generateCompressSizes(compressSizes);
        return uploadService.uploadFile(storageProvider, file, UploadTypeEnum.IMAGE.getAllowedExts(), UploadTypeEnum.IMAGE.getMaxSize(), uploadOptions);
    }

    @PostMapping("admin/update-shelf-status")
    @SysLog(description = "后台更新商品上架状态")
    public ResponseStatusVO updateShelfStatus(@RequestBody GoodsInfoVO goodsInfoVO) {
        if (null == goodsInfoVO.getId() || org.apache.commons.lang.StringUtils.isEmpty(goodsInfoVO.getId().toString())) {
            return ResponseStatusVO.error("ID为空", null);
        }
        if (null == goodsInfoVO.getShelfStatus() || org.apache.commons.lang.StringUtils.isEmpty(goodsInfoVO.getShelfStatus().toString())) {
            return ResponseStatusVO.error("状态为空", null);
        }
        Object obj = goodsInfoService.getById(goodsInfoVO.getId());
        if (null == obj) {
            return ResponseStatusVO.error("商品不存在", null);
        }
        return updateGoodsInfo(goodsInfoVO);
    }

    /**
     * 前端更新点击量
     * @param goodsId
     * @return
     */
    @GetMapping("any/goods/click-count/{goodsId}")
    public ResponseStatusVO userUpdateClickCount(@PathVariable("goodsId") Long goodsId) {
        goodsInfoService.updateClickCount(goodsId);
        return ResponseStatusVO.ok("更新点击量", null);
    }

    private ResponseStatusVO updateGoodsInfo(GoodsInfoVO goodsInfoVO) {
        int updateRows = goodsInfoService.update(BeanUtils.copy(goodsInfoVO, GoodsInfoDTO.class));
        if (updateRows == 1) {
            return ResponseStatusVO.ok("更新成功", null);
        } else {
            return ResponseStatusVO.dataError("数据版本号有问题，在此更新前数据已被更新", null);
        }
    }

    /**
     * 计算指定sku的活动数据
     * @param shopId 店铺id
     * @param goodsId 商品id
     * @param goodsSkuIds sku的id数组
     * @return
     */
    @PostMapping("admin/list-sku-count")
    public ResponseStatusVO listCountGoodsSkuActivity(Long shopId, Long goodsId, String goodsSkuIds) {
        String[] skuIds = goodsSkuIds.split(",");
        List<GoodsSkuActivityDTO> goodsSkuActivityDTOList = goodsInfoService.listCountActivityGoods(shopId, goodsId, skuIds);
        List<GoodsSkuActivityVO> goodsSkuActivityVOList = BeanUtils.copy(goodsSkuActivityDTOList, GoodsSkuActivityVO.class);
        return ResponseStatusVO.ok("查询成功", goodsSkuActivityVOList);
    }

    /**
     * 前端计算指定sku的活动数据
     * @param shopId 店铺id
     * @param goodsId 商品id
     * @param goodsSkuIds sku的id数组
     * @return
     */
    @PostMapping("any/list-sku-count")
    public ResponseStatusVO anyListCountGoodsSkuActivity(Long shopId, Long goodsId, String goodsSkuIds) {
        return listCountGoodsSkuActivity(shopId, goodsId, goodsSkuIds);
    }

    @Autowired
    public void setGoodsInfoService(GoodsInfoService goodsInfoService) {
        this.goodsInfoService = goodsInfoService;
    }

    @Autowired
    public void setUploadService(UploadService uploadService) {
        this.uploadService = uploadService;
    }
}
